/*
 * et2_edb.c - edbtool2 edb library adaption layer
 * Clunix, cezanne@clunix.com, 2004.12.20.
 *
 * Copyright (c) 2001-2008 by Clunix Inc. All Rights Reserved.
 */

#include "config.h"

#include "edbtool2.h"
#include "eds.h"
#include "et2_edb.h"

static et2_edb_t *
create_et2_edb(ECMBOOL fakemode)
{
	et2_edb_t	*pet2_edb;

	pet2_edb = ecm_malloc(sizeof(et2_edb_t));
	memset(pet2_edb, 0, sizeof(et2_edb_t));
	pet2_edb->fakemode = fakemode;
	return pet2_edb;
}

static void
free_et2_edb(et2_edb_t *pet2_edb)
{
	ecm_free(pet2_edb->snapshot);
	sr_free(pet2_edb->sr_snapshot_conf);
	sr_free(pet2_edb->sr_edbroot);
	ecm_free(pet2_edb);
}

et2_edb_t *
et2_edb_connect(const char *ipstr, ecm_uint16 port, const char *mdname)
{
	et2_edb_t	*pet2_edb;
	edb_t		*edb = NULL;
	ecm_ebc_t	ecm_ebc;
	extern ECMBOOL	master_connection;
	ebc_ndid_t	ndid;
	extern char	*username;
	char		*passwd = NULL;
	edb_err_t	err;

	pet2_edb = create_et2_edb(ECM_FALSE);
	if (username == NULL)
		passwd = NULL;
	else {
		ecm_readline_setmode(ECM_READLINE_NOECHO);
		passwd = ecm_readline("Password: ");
		ecm_readline_setmode(ECM_READLINE_ECHO);
	}

	if (ebc_connect(ipstr, port, mdname, 5000, &ecm_ebc) != EBC_OK) {
		fprintf(stderr, "%s:%hu:ebc connection failed\n",
			ecm_safe_str(ipstr), port);
		goto out;
	}

	ndid = (master_connection) ? EBC_NDID_NONE: EBC_NDID_SELF;
	if ((err = edb_connect_node(ecm_ebc, ndid, username, passwd, &edb)) < 0) {
		ebc_close(ecm_ebc);
		switch (err) {
		case -ERR_EDB_AUTH:
		case -ERR_EDB_INVALIDARG:
			if (ecm_empty_str(username))
				fprintf(stderr, "access denied. username required.\n");
			else
				fprintf(stderr, "access denied!!\n");
			break;
		default:
			fprintf(stderr, "cannot connect to edb\n");
			break;
		}
	}
	else
		pet2_edb->ed = edb;
out:
	if (edb == NULL) {
		free_et2_edb(pet2_edb);
		pet2_edb = NULL;
	}
	ecm_free(passwd);
	return pet2_edb;
}

et2_edb_t *
et2_edb_connect_fake(const char *snapshot)
{
	et2_edb_t	*pet2_edb;
	eds_err_t	err;

	pet2_edb = create_et2_edb(ECM_TRUE);
	err = eds_read_snapshot(snapshot);

	switch (err) {
	case EDS_OK:
		pet2_edb->sr_snapshot_conf = sr_eds_conf;
		pet2_edb->sr_edbroot = sr_eds_root;

		pet2_edb->snapshot = ecm_strdup(snapshot);
		pet2_edb->sr_cwd = pet2_edb->sr_edbroot;
		return pet2_edb;
	case -ERR_EDS_NOTEXIST:
		fprintf(stderr, "snapshot file not found: %s\n", snapshot);
		break;
	default:
		fprintf(stderr, "cannot open snapshot file: %s\n", snapshot);
		break;
	}
	free_et2_edb(pet2_edb);
	return NULL;
}

edb_err_t
et2_edb_get_field(et2_edb_t *pet2_edb, edb_field_t field, const char *LNP, const char *EDExpr, int opt, sr_t **psr_res)
{
	if (!pet2_edb->fakemode)
		return edb_get_field(pet2_edb->ed, field, LNP, EDExpr, opt, psr_res);
	else
		return edb_get_field_fake(pet2_edb, field, LNP, EDExpr, opt, psr_res);
}

edb_err_t
et2_edb_get_modinfos(et2_edb_t *pet2_edb, sr_t **psr_res)
{
	if (!pet2_edb->fakemode)
		return edb_get_modinfos(pet2_edb->ed, psr_res);
	else
		return edb_get_modinfos_fake(pet2_edb, psr_res);
}

edb_err_t
et2_edb_set_field(et2_edb_t *pet2_edb, edb_field_t field, const char *LNP, const char *EDExpr, const char *asrv, int opt)
{
	if (!pet2_edb->fakemode)
		return edb_set_field(pet2_edb->ed, field, LNP, EDExpr, asrv, opt);
	else
		return edb_set_field_fake(pet2_edb, field, LNP, EDExpr, asrv, opt);
}

void
et2_edb_close(et2_edb_t *pet2_edb)
{
	if (!pet2_edb->fakemode)
		edb_close(pet2_edb->ed);
	free_et2_edb(pet2_edb);
}

edb_err_t
et2_edb_create_sr(et2_edb_t *pet2_edb, const char *LNP, const char *EDExpr, sr_t *sr)
{
	if (!pet2_edb->fakemode)
		return edb_create_sr(pet2_edb->ed, LNP, EDExpr, sr);
	else
		return edb_create_sr_fake(pet2_edb, LNP, EDExpr, sr);
}

edb_err_t
et2_edb_xecreate(et2_edb_t *pet2_edb, const char *LNP, const char *EDExpr, const char *srname, const char *srtstr, sr_t **psr_res)
{
	if (pet2_edb->fakemode)
		return -ERR_EDB_NOTSUPPORTED;
	return edb_xecreate(pet2_edb->ed, LNP, EDExpr, srname, srtstr, psr_res);
}

edb_err_t
et2_edb_xedelete(et2_edb_t *pet2_edb, const char *LNP, const char *EDExpr, ECMBOOL force, sr_t **psr_res)
{
	if (pet2_edb->fakemode)
		return -ERR_EDB_NOTSUPPORTED;
	return edb_xedelete(pet2_edb->ed, LNP, EDExpr, force, psr_res);
}

edb_err_t
et2_edb_cd(et2_edb_t *pet2_edb, const char *LNP, const char *EDExpr, char **pcwd)
{
	if (!pet2_edb->fakemode)
		return edb_cd(pet2_edb->ed, LNP, EDExpr, pcwd);
	return edb_cd_fake(pet2_edb, LNP, EDExpr, pcwd);
}

edb_err_t
et2_edb_del(et2_edb_t *pet2_edb, const char *LNP, const char *EDExpr, int opt)
{
	if (!pet2_edb->fakemode)
		return edb_del(pet2_edb->ed, LNP, EDExpr, opt);
	else
		return edb_del_fake(pet2_edb, LNP, EDExpr, opt);
}

edb_err_t
et2_edb_exec(et2_edb_t *pet2_edb, const char *EDExpr, sr_t **psr_res)
{
	if (!pet2_edb->fakemode)
		return edb_exec(pet2_edb->ed, EDExpr, psr_res, 0);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_snapshot(et2_edb_t *pet2_edb)
{
	if (!pet2_edb->fakemode)
		return edb_snapshot(pet2_edb->ed);
	else
		return edb_snapshot_fake(pet2_edb);
}

edb_err_t
et2_edb_elect(et2_edb_t *pet2_edb)
{
	if (!pet2_edb->fakemode)
		return edb_elect_master(pet2_edb->ed);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_shutdown(et2_edb_t *pet2_edb, const char *LNP)
{
	if (!pet2_edb->fakemode)
		return edb_shutdown(pet2_edb->ed, LNP);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_getinheritedtypes_cmd(et2_edb_t *pet2_edb, srt_t srt_super, sr_t **psr_ret)
{
	if (!pet2_edb->fakemode)
		return edb_get_inherited_types(pet2_edb->ed, srt_super, psr_ret);
	return -ERR_EDB_NOTSUPPORTED;
}

#ifdef ECM_DEBUG

edb_err_t
et2_edb_dbgset(et2_edb_t *pet2_edb, const char *mdname, const char *dbgset)
{
	if (!pet2_edb->fakemode)
		return edb_dbgset(pet2_edb->ed, mdname, dbgset);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_mtrace_info(et2_edb_t *pet2_edb, sr_t **psr_res)
{
	if (!pet2_edb->fakemode)
		return edb_mtrace_info(pet2_edb->ed, psr_res);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_mtrace_on(et2_edb_t *pet2_edb, ecm_uint32 level)
{
	if (!pet2_edb->fakemode)
		return edb_mtrace_on(pet2_edb->ed, level);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_mtrace_off(et2_edb_t *pet2_edb)
{
	if (!pet2_edb->fakemode)
		return edb_mtrace_off(pet2_edb->ed);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_mtrace_clear(et2_edb_t *pet2_edb)
{
	if (!pet2_edb->fakemode)
		return edb_mtrace_clear(pet2_edb->ed);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_mtrace_report(et2_edb_t *pet2_edb, sr_t **psr_traces)
{
	if (!pet2_edb->fakemode)
		return edb_mtrace_report(pet2_edb->ed, psr_traces);
	return -ERR_EDB_NOTSUPPORTED;
}

edb_err_t
et2_edb_treelock_info(et2_edb_t *pet2_edb, sr_t **psr_res)
{
	if (!pet2_edb->fakemode)
		return edb_treelock_info(pet2_edb->ed, psr_res);
	return -ERR_EDB_NOTSUPPORTED;
}

#endif
